From e69550b83aef6e4cb61602239cde612355d3d27c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 25 May 2005 13:07:42 +0000 Subject: [PATCH] bitkeeper revision 1.1551 (4294789ea5Ghsn6s5aIMFHK5LY4uSw) Add 64-bit (cmpxchg8b) support to the cmpxchg() macro for x86_32. Signed-off-by: Keir Fraser --- xen/include/asm-x86/system.h | 51 ++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h index cd0619008d..a614d11b4a 100644 --- a/xen/include/asm-x86/system.h +++ b/xen/include/asm-x86/system.h @@ -2,6 +2,7 @@ #define __ASM_SYSTEM_H #include +#include #include /* Clear and set 'TS' bit respectively */ @@ -70,8 +71,8 @@ static always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, * indicated by comparing RETURN with OLD. */ -static always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) +static always_inline unsigned long __cmpxchg( + volatile void *ptr, unsigned long old, unsigned long new, int size) { unsigned long prev; switch (size) { @@ -113,9 +114,49 @@ static always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long o } #define __HAVE_ARCH_CMPXCHG -#define cmpxchg(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) + +#if BITS_PER_LONG == 64 + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ + (unsigned long)(n),sizeof(*(ptr)))) +#else + +static always_inline unsigned long long __cmpxchg8b( + volatile void *ptr, unsigned long long old, unsigned long long new) +{ + unsigned long long prev; + __asm__ __volatile__ ( + LOCK_PREFIX "cmpxchg8b %3" + : "=A" (prev) + : "c" ((u32)(new>>32)), "b" ((u32)new), + "m" (*__xg((volatile void *)ptr)), "0" (old) + : "memory" ); + return prev; +} + +#define cmpxchg(ptr,o,n) \ +({ \ + __typeof__(*(ptr)) __prev; \ + switch ( sizeof(*(ptr)) ) { \ + case 8: \ + __prev = ((__typeof__(*(ptr)))__cmpxchg8b( \ + (ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))); \ + break; \ + default: \ + __prev = ((__typeof__(*(ptr)))__cmpxchg( \ + (ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))); \ + break; \ + } \ + __prev; \ +}) + +#endif /* -- 2.30.2